package com.tanhua.server.service;

import com.tanhua.commons.exception.TanHuaException;
import com.tanhua.commons.templates.OssTemplate;
import com.tanhua.domain.db.UserInfo;
import com.tanhua.domain.mongo.Publish;
import com.tanhua.domain.mongo.Visitor;
import com.tanhua.domain.vo.*;
import com.tanhua.dubbo.api.UserInfoApi;
import com.tanhua.dubbo.api.mongo.PublishApi;
import com.tanhua.dubbo.api.mongo.RecommendUserApi;
import com.tanhua.dubbo.api.VisitorApi;
import com.tanhua.server.interceptor.UserHolder;
import com.tanhua.server.utils.RelativeDateFormat;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.RandomUtils;
import org.apache.dubbo.config.annotation.Reference;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 圈子模块
 */
@Service
@Slf4j
public class MomentService {
    //订阅图片模板
    @Autowired
    private OssTemplate ossTemplate;

    //订阅 userInfo 用户详情
    @Reference
    private UserInfoApi userInfoApi;

    //订阅 动态 PublishApi
    @Reference
    private PublishApi publishApi;

    @Reference
    private RecommendUserApi recommendUserApi;

    @Reference
    private VisitorApi visitorApi;

    @Autowired
    private RedisTemplate redisTemplate;

    /**
     * 发布动态
     *
     * @param publishVo
     * @param imageContent
     */
    public void postMoment(PublishVo publishVo, MultipartFile[] imageContent) {
        //1.获取登录用户id
        Long loginUserID = UserHolder.getUserId();

        //2.把图片上传到阿里云
        List<String> imgList = new ArrayList<>();
        try {
            if (imageContent != null) {
                for (MultipartFile multipartFile : imageContent) {
                    String img = ossTemplate.upload(multipartFile.getOriginalFilename(), multipartFile.getInputStream());
                    imgList.add(img);
                }
            }
        } catch (IOException e) {
            log.info("图片上传失败。。", e);
            throw new TanHuaException("图片上传失败");
        }
        //3.把vo转成pojo
        Publish publish = new Publish();
        BeanUtils.copyProperties(publishVo, publish);
        //4.动态发布的作者--登录用户的id
        publish.setUserId(loginUserID);
        publish.setState(0);//未审核
        //5.pojo设置图片地址
        publish.setMedias(imgList);
        publish.setSeeType(1); // 公开
        publish.setLongitude(publishVo.getLocation()); //位置信息
        //6.调用api发布动态
        publishApi.add(publish);
    }

    /**
     * 好友动态--2.0
     *
     * @param page
     * @param pagesize
     * @return
     */
    public PageResult<MomentVo> queryFriendPublishList(Long page, Long pagesize) {

        //获取登录用户id
        Long loginUserID = UserHolder.getUserId();
        //通过登录用户id,分页查询好友动态(查询朋友的时间线表)
        PageResult pageResult = publishApi.findFriendPublishByTimeline(page, pagesize, loginUserID);
        //获取查询的结果集（动态结果）
        List<Publish> publishList = pageResult.getItems();
        //判断结果集中有没有数据
        if (!CollectionUtils.isEmpty(publishList)) {

            //for (Publish publish : publishList)  //遍历结果集，查询用户详情
            //使用流改进,获取所有动态作者id
            List<Long> UserIdS = publishList.stream().map(Publish::getUserId).collect(Collectors.toList());

            //查询好友的详情
            //UserInfo publishUser = userInfoApi.findById(publishUserId);
            //批量查询好友详情
            List<UserInfo> userInfoList = userInfoApi.findByBatchId(UserIdS);

            //把作者信息转成map,id-->key,userInfo-->value
            Map<Long, UserInfo> userInfoMap = userInfoList.stream().collect(Collectors.toMap(UserInfo::getId, u -> u));

            //把动态转成 MomentVo
            List<MomentVo> voList = publishList.stream().map(publish -> {
                MomentVo momentVo = new MomentVo();
                BeanUtils.copyProperties(publish, momentVo);

                //作者信息
                UserInfo userInfo = userInfoMap.get(publish.getUserId());

                //设置标签tags
                momentVo.setTags(StringUtils.split(userInfo.getTags(), ","));
                //复制动态属性 publish-->momentVo

                BeanUtils.copyProperties(userInfo, momentVo);
                //设置动态id
                momentVo.setId(publish.getId().toHexString());
                //复制图片，将集合转成数组
                momentVo.setImageContent(publish.getMedias().toArray(new String[]{}));
                //设置发布时间
                momentVo.setCreateDate(publish.getCreated().toString());
                // 默认距离
                momentVo.setDistance("100米");
                momentVo.setHasLiked(0);  //是否点赞  0：未点 1:点赞

                momentVo.setHasLoved(0);  //是否喜欢  0：未点 1:点赞
                //设置时间
                momentVo.setCreateDate(RelativeDateFormat.format(new Date(publish.getCreated())));

                //是否点赞

                String key = "publish_like_" + loginUserID + "_" + momentVo.getId();
                if (redisTemplate.opsForValue().get(key) != null) {
                    momentVo.setHasLiked(1);
                }


                return momentVo;
            }).collect(Collectors.toList());
            //更新pageResult
            pageResult.setItems(voList);
        }

        //返回
        return pageResult;
    }

    /**
     * 好友动态--1.0
     *
     * @param page
     * @param pagesize
     * @return
     */
    public PageResult<MomentVo> queryFriendPublishList_2(Long page, Long pagesize) {

        //获取登录用户id
        Long loginUserID = UserHolder.getUserId();
        //通过登录用户id,分页查询好友动态(查询朋友的时间线表)
        PageResult pageResult = publishApi.findFriendPublishByTimeline(page, pagesize, loginUserID);
        //获取查询的结果集（动态结果）
        List<Publish> publishList = pageResult.getItems();
        //遍历结果集，查询用户详情
        //构建vo
        List<MomentVo> momentVoList = new ArrayList<>();
        for (Publish publish : publishList) {
            //获取好友的id（动态发布者的id）
            Long publishUserId = publish.getUserId();
            //查询好友的详情
            UserInfo publishUser = userInfoApi.findById(publishUserId);

            //复制用户详情，userInfo-->momentVoList
            MomentVo momentVo = new MomentVo();
            BeanUtils.copyProperties(userInfoApi, momentVo);
            //设置标签tags
            momentVo.setTags(StringUtils.split(publishUser.getTags(), ","));


            //复制动态属性 publish-->momentVo
            BeanUtils.copyProperties(publish, momentVo);
            //设置动态id
            momentVo.setId(publish.getId().toHexString());
            //复制图片，将集合转成数组
            momentVo.setImageContent(publish.getMedias().toArray(new String[]{}));
            //设置发布时间
            momentVo.setCreateDate(publish.getCreated().toString());
            // 默认距离
            momentVo.setDistance("100米");
            momentVo.setHasLiked(0);  //是否点赞  0：未点 1:点赞
            momentVo.setHasLoved(0);  //是否喜欢  0：未点 1:点赞

            //设置时间
            momentVo.setCreateDate(RelativeDateFormat.format(new Date(publish.getCreated())));

            //添加到list集合中
            momentVoList.add(momentVo);

        }

        //更新pageResult
        pageResult.setItems(momentVoList);

        //返回
        return pageResult;
    }

    /**
     * 推荐动态
     *
     * @param page
     * @param pagesize
     * @return
     */
    public PageResult<PublishVo> queryRecommendPublishList(Long page, Long pagesize) {
        //1.获取登录用户id
        Long loginUserID = UserHolder.getUserId();

        //2.通过登陆用户id查询自己的时间线表与动态的数据
        PageResult pageResult = publishApi.queryRecommendPublishList(page, pagesize, loginUserID);

        //3.获取查询的结果集（动态结果）
        List<Publish> publishList = pageResult.getItems();

        //构建vo
        List<MomentVo> momentVoList = new ArrayList<>();

        //遍历结果集，查询用户详情
        if (!CollectionUtils.isEmpty(publishList)) {

            for (Publish publish : publishList) {

                //构建momentvo
                MomentVo momentVo = new MomentVo();

                //获取好友的id（动态发布者的id）
                //查询好友的详情
                UserInfo userInfoUser = userInfoApi.findById(publish.getUserId());

                //复制用户详情，userInfoUser -->momentVoList
                BeanUtils.copyProperties(userInfoUser, momentVo);


                //设置用户id
                momentVo.setUserId(userInfoUser.getId());
                momentVo.setId(publish.getId().toHexString());
                //设置用户标签
                momentVo.setTags(StringUtils.split(userInfoUser.getTags(), ","));

                //复制用户详情publish-->momentVoList
                BeanUtils.copyProperties(publish, momentVo);

                //赋值图片  list集合转换成string数组
                momentVo.setImageContent(publish.getMedias().toArray(new String[]{}));

                //设置距离
                momentVo.setDistance("500米");

                //设置发布时间
                momentVo.setCreateDate(publish.getCreated().toString());
                momentVo.setHasLiked(0);  //是否点赞  0：未点 1:点赞
                momentVo.setHasLoved(0);  //是否喜欢  0：未点 1:点赞

                //设置时间
                momentVo.setCreateDate(RelativeDateFormat.format(new Date(publish.getCreated())));

                //是否点赞
                String key = "publish_like_" + loginUserID + "_" + momentVo.getId();
                if (redisTemplate.opsForValue().get(key) != null) {
                    momentVo.setHasLiked(1);
                }

                //添加到list集合中
                momentVoList.add(momentVo);
            }
        }
        //返回
        pageResult.setItems(momentVoList);
        return pageResult;
    }

    /**
     * 查询用户动态
     *
     * @param page
     * @param pagesize
     * @param userId
     * @return
     */
    public PageResult<MomentVo> queryMyPublishList(Long page, Long pagesize, Long userId) {
        //默认是查询用户动态的
        Long loginUserId = userId; //登录用户id
        Long targetUserId = loginUserId; //目标用户id
        if (userId != null) {
            //如果参数userId有值的话，就查询目标用户动态
            targetUserId = userId;
        }
        //调用api查询给登录用户自己的动态
        PageResult pageResult = publishApi.findMyPublishList(page, pagesize, targetUserId);
        List<Publish> publishList = pageResult.getItems();
        if (!CollectionUtils.isEmpty(publishList)) {
            //补全用户信息
            //所有动态的作者都是自己,调用api批量查询用户信息
            UserInfo userInfo = userInfoApi.findById(targetUserId);
            //把动态转成MomentVO
            List<MomentVo> momentVoList = publishList.stream().map(publish -> {
                MomentVo momentVo = new MomentVo();
                //复制用户的信息 publish-->momentvo
                BeanUtils.copyProperties(publish, momentVo);
                //设置动态信息
                momentVo.setImageContent(publish.getMedias().toArray(new String[]{}));//图片
                momentVo.setDistance("500米"); // 距离
                momentVo.setCreateDate(RelativeDateFormat.format(new Date(publish.getCreated()))); //发布时间
                momentVo.setId(publish.getId().toHexString());// 动态的id

                //复制用户的信息 userInfo-->momentVo
                BeanUtils.copyProperties(userInfo, momentVo);
                momentVo.setTags(StringUtils.split(userInfo.getTags(), ","));//用户标签

                //是否点赞
                String key = "publish_like_" + loginUserId + "_" + momentVo.getId();
                if (redisTemplate.opsForValue().get(key) != null) {
                    momentVo.setHasLiked(1);
                }

                return momentVo;
            }).collect(Collectors.toList());
            //设置到PageResult
            pageResult.setItems(momentVoList);
        }
        return pageResult;
    }

    /**
     * 查询单条动态
     *
     * @param publishId
     * @return
     */
    public MomentVo findById(String publishId) {
        // 1. 调用api查询单条动态
        Publish publish = publishApi.findById(publishId);
        //2.查询动态作者的id
        Long publishUserId = publish.getUserId(); //动态作者的id
        // 3. 查询作者的详情
        UserInfo userInfo = userInfoApi.findById(publishUserId);
        //4.构建vo
        MomentVo vo = new MomentVo();


        BeanUtils.copyProperties(publish, vo);

        BeanUtils.copyProperties(userInfo, vo);

        //设置标签
        vo.setTags(StringUtils.split(userInfo.getTags(), ","));

        vo.setImageContent(publish.getMedias().toArray(new String[0])); //媒体数据

        vo.setDistance("500米"); //距离
        vo.setCreateDate(RelativeDateFormat.format(new Date(publish.getCreated()))); //发布时间

        // 动态的id
        vo.setId(publish.getId().toHexString());

        Long loginUserId = UserHolder.getUserId(); //登录用户id

        vo.setHasLiked(0); //默认是0
        String key = "publish_like_" + loginUserId + "_" + vo.getId();
        if (redisTemplate.opsForValue().get(key) != null) {
            vo.setHasLiked(1); //点赞过了
        }
        // 是否喜欢处理
        vo.setHasLoved(0); //默认不喜欢
        key = "publish_love_" + loginUserId + "_" + vo.getId();
        if (redisTemplate.hasKey(key)) {
            // 喜欢过了
            vo.setHasLoved(1);// 1: 喜欢过了
        }

        return vo;
    }

    /**
     * 谁看过我
     *
     * @return
     */
    public List<VisitorVo> queryVisitors() {
        //1. 取出redis中设置上次查询时间
        String key = "visitors_time_" + UserHolder.getUserId();
        Long lastQueryTime = (Long) redisTemplate.opsForValue().get(key);
        //如果存在，就查询前四条访问记录
        //如果不存在，就按时间降序取前四条访客
        List<Visitor> visitorList = visitorApi.queryLast4Visitors(lastQueryTime, UserHolder.getUserId());

        List<VisitorVo> voList = new ArrayList<>();
        if (!CollectionUtils.isEmpty(visitorList)) {
            //取出所有访客id集合
            List<Long> longListId = visitorList.stream().map(Visitor::getVisitorUserId).collect(Collectors.toList());

            //查询所有访客信息
            List<UserInfo> userInfoList = userInfoApi.findByBatchId(longListId);

            //转成map
            Map<Long, UserInfo> userInfoMap = userInfoList.stream().collect(Collectors.toMap(UserInfo::getId, u -> u));

            //复制属性
           voList = visitorList.stream().map(visitor -> {
                VisitorVo vo = new VisitorVo();

                //获取用户详细信息
                UserInfo userInfo = userInfoMap.get(visitor.getVisitorUserId());

                BeanUtils.copyProperties(userInfo, vo);

                //赋值tags
                vo.setTags(StringUtils.split(userInfo.getTags(), ","));

                //缘分值
                if (null==visitor.getScore()) {
                    //设置默认值
                    vo.setFateValue(RandomUtils.nextInt(60,80));
                } else {
                    vo.setFateValue(visitor.getScore().intValue());
                }
                return vo;
            }).collect(Collectors.toList());
        }
        // 存入redis最后一次查询的时间，这里注释它，方便测试 TODO
        //redisTemplate.opsForValue().set(key,Long.valueOf(System.currentTimeMillis()));

        return voList;

    }
}